package cn.topevery.garden.wapi.component;

import hw.topevery.af.entity.bo.ActivityInstanceBo;
import hw.topevery.af.entity.bo.RuntimeWorkflow;
import hw.topevery.af.entity.enums.ReceiveTypeEnum;
import hw.topevery.af.entity.po.ActivityInstance;
import hw.topevery.af.entity.po.WorkflowInstance;
import hw.topevery.af.entity.vo.*;
import hw.topevery.af.runtime.WorkflowDefineManager;
import hw.topevery.af.runtime.WorkflowRuntimeManager;
import hw.topevery.basis.dal.dao.SysDeptDao;
import hw.topevery.basis.dal.dao.SysRoleDao;
import hw.topevery.basis.dal.dao.SysUserDao;
import hw.topevery.basis.entity.po.SysDept;
import hw.topevery.basis.entity.po.SysRole;
import hw.topevery.basis.entity.po.SysUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

@Component
public class WfHelper {
    @Autowired
    WorkflowDefineManager workflowDefineManager;

    @Autowired
    WorkflowRuntimeManager workflowRuntimeManager;

    @Autowired
    SysUserDao sysUserDao;

    @Autowired
    SysDeptDao sysDeptDao;

    @Autowired
    SysRoleDao sysRoleDao;

    /**
     * @param workflowId
     * @return
     * @throws Exception
     */
    public RuntimeWorkflow getRunWorkflow(String workflowId) throws Exception {
        return workflowDefineManager.getRunWorkflow(workflowId);
    }

    /*
     * 启动工作流
     * @return
     * @throws Exception
     */
    public StartResult startWorkflow(StartPara startPara) throws Exception {
        startPara.setDate(LocalDateTime.now());                           // 来件时间

        // 判断来件人是否为空
        if (StringUtils.isBlank(startPara.getUserName())) {
            SysUser entity = sysUserDao.getEntityByDataId(startPara.getUserId());
            if (entity != null) {
                startPara.setUserName(entity.userName);
            }
        }

        // 判断接收对象是否为空
        if (StringUtils.isBlank(startPara.getReceiverName())) {
            String name = getReceiverName(startPara.getReceiverType(), startPara.getReceiverId());
            startPara.setReceiverName(name);
        }

        return workflowRuntimeManager.startActivity(startPara);
    }


    /**
     * 启动工作流
     *
     * @return
     * @throws Exception
     */
    public StartResult startWorkflow(String formUniqueId, String userId) throws Exception {
        StartPara startPara = new StartPara();
        startPara.setWfIdentifier("51CBA141-56FA-44DF-8187-277B20662460"); // 流程实例标识
        startPara.setFormUniqueId(formUniqueId); // 业务表单标识
        startPara.setReceiverType(ReceiveTypeEnum.USER);                  // 接收对象
        startPara.setReceiverId(userId);  // 接收对象Id
        startPara.setUserId(userId);      // 来件人
        startPara.setDate(LocalDateTime.now());                           // 来件时间
//        startPara.setLimit(10);                                           // 环节时限
        return startWorkflow(startPara);
    }

    /**
     * 工作流正常发送，默认先签收
     *
     * @param sendPara 当前环节 更新
     * @param sendAct  下一环节 相关值
     * @return
     * @throws Exception
     */
    public SingleResult sendActivity(SendPara sendPara, SendActivityPara sendAct) throws Exception {
        return sendActivity(sendPara, sendAct, true);
    }

    /**
     * 工作流正常发送
     *
     * @param sendPara 当前环节 更新
     * @param sendAct  下一环节 相关值
     * @param signed   true: 签收 false: 不签收
     * @return
     * @throws Exception
     */
    public SingleResult sendActivity(SendPara sendPara, SendActivityPara sendAct, Boolean signed) throws Exception {

        if (StringUtils.isBlank(sendPara.getUserName())) {
            sendPara.setUserName(getUserName(sendPara.getUserId()));
        }

        if (StringUtils.isBlank(sendAct.getReceiverName())) {
            sendAct.setReceiverName(getReceiverName(sendAct.getReceiverType(), sendAct.getReceiverId()));
        }
        if (signed) {
            SingleResult res = signedActivity(sendPara.getCurrentInstId(), sendPara.getUserId());
            // 签收失败，返回
            if (!res.isSuccess) {
                return res;
            }
        }
        return workflowRuntimeManager.sendActivity(sendPara, sendAct);
    }

    /**
     * 多路发送
     *
     * @param para
     * @param list
     * @return
     * @throws Exception
     */
    public MultiResult sendActivity(SendPara para, List<SendActivityPara> list) throws Exception {
        if (StringUtils.isBlank(para.getUserName())) {
            para.setUserName(getUserName(para.getUserId()));
        }
        for (int i = 0; i < list.size(); i++) {
            SendActivityPara item = list.get(i);
            if (StringUtils.isBlank(item.getReceiverName())) {
                item.setReceiverName(getReceiverName(item.getReceiverType(), item.getReceiverId()));
            }
        }
        return workflowRuntimeManager.sendActivity(para, list);
    }


    /**
     * 签收
     *
     * @param activityInstanceId
     * @param userId             签收人
     * @param userName           签收人名称
     * @return
     */
    public SingleResult signedActivity(String activityInstanceId, String userId, String userName) throws Exception {
        if (StringUtils.isBlank(userName)) {
            userName = getUserName(userId);
        }
        SignResult signResult = workflowRuntimeManager.signedActivity(activityInstanceId, userId, userName);
        // 注意 此处将返回对象做了转换
        SingleResult res = new SingleResult();
        res.setSuccess(false);
        res.setErrorMessage(signResult.errorMessage);
        res.setInstance(signResult.getInstance());
        return res;
    }

    /**
     * 签收
     *
     * @param activityInstanceId
     * @param userId             签收人
     * @return
     * @throws Exception
     */
    public SingleResult signedActivity(String activityInstanceId, String userId) throws Exception {
        return signedActivity(activityInstanceId, userId, "");
    }

    /**
     * 撤消签收
     *
     * @param activityInstanceId 环节实例ID
     * @param userId             用户Id
     * @return 结果
     */
    public SignResult unSignActivity(String activityInstanceId, String userId) {
        SignResult result = workflowRuntimeManager.unSignActivity(activityInstanceId, userId);
        return result;
    }

    /**
     * 流程实例信息
     *
     * @param wfInstID 流程实例Id
     * @return
     */
    public WorkflowInstance getWorkflowInstance(String wfInstID) {
        return this.workflowRuntimeManager.getWorkflowInstance(wfInstID);
    }

    /**
     * 环节实例信息
     *
     * @param actInstID 环节实例Id
     * @return
     * @throws Exception
     */
    public ActivityInstanceBo getActivityInstance(String actInstID) throws Exception {
        return this.workflowRuntimeManager.getActivityInstance(actInstID);
    }

//    /**
//     *
//     * @param actInstId
//     * @return
//     */
//    public ActivityInstance gtRuntimeActivityInstance(String actInstId) {
//        return this.workflowRuntimeManager.gtRuntimeActivityInstance(actInstId);
//    }

    /**
     * 获取环节中 待办环节
     *
     * @param wfInstID 工作流实例Id
     * @return
     */
    public List<ActivityInstance> getCurrentActivityInstance(String wfInstID) {
        return this.workflowRuntimeManager.getCurrentActivityInstance(wfInstID);
    }

//    /**
//     * 获取环节中 待办环节  和getCurrentActivityInstance一样
//     * @param wfInstID  工作流实例Id
//     * @return
//     */
//    public List<ActivityInstance> getRuntimeActivityInstanceList(String wfInstID) {
//        return this.workflowRuntimeManager.getRuntimeActivityInstanceList(wfInstID);
//    }


    /**
     * 获取环节列表
     *
     * @param wfInstId 工作流实例Id
     * @return
     */
    public List<ActivityInstance> getActivityInstanceList(String wfInstId) {
        return this.workflowRuntimeManager.getActivityInstanceList(wfInstId);
    }


    /**
     * 重启工作流,并调度到指定的环节  工作流必须结束
     *
     * @param wfInstId
     * @param para
     * @param sendAct
     * @return
     * @throws Exception
     */
    public SingleResult rebootActivity(String wfInstId, SendPara para, SendActivityPara sendAct) throws Exception {
        return this.workflowRuntimeManager.rebootActivity(wfInstId, para, sendAct);
    }

    /**
     * 程重新启动,直接重启到上一环节   工作流必须结束
     *
     * @param para
     * @return
     * @throws Exception
     */
    public SingleResult rebootActivity(BackPara para) throws Exception {
        return this.workflowRuntimeManager.rebootActivity(para);
    }

    /**
     * 特殊发送
     *
     * @param para
     * @param sendAct
     * @return
     */
    public SingleResult specialActivity(SendPara para, SendActivityPara sendAct) throws Exception {
        return this.workflowRuntimeManager.specialActivity(para, sendAct);
    }

    /**
     * 自由发送,不验证路由定义，如果isBuildInst为false,则不写入下一环节
     * 如，关闭当前环节，list可不填，isBuildInst为false即
     *
     * @param para        发送参数
     * @param list        发送环节
     * @param isBuildInst 是否产生新环节
     * @return
     * @throws Exception
     */
    public MultiResult freeActivity(SendPara para, List<SendActivityPara> list, boolean isBuildInst) throws Exception {
        return this.workflowRuntimeManager.freeActivity(para, list, isBuildInst);
    }

    /**
     * 工作流撤件
     *
     * @param para 参数
     * @return 结果
     */
    public SingleResult revokeActivity(BackPara para) throws Exception {
        if (StringUtils.isBlank(para.getUserName())) {
            para.setUserName(getUserName(para.getUserId()));
        }
        return this.workflowRuntimeManager.revokeActivity(para);
    }

    /**
     * 工作流退件
     *
     * @param para 工作流退件
     * @return 结果
     */
    public SingleResult untreadActivity(BackPara para) throws Exception {
        if (StringUtils.isBlank(para.getUserName())) {
            para.setUserName(getUserName(para.getUserId()));
        }
        return this.workflowRuntimeManager.untreadActivity(para);
    }

    public String getReceiverName(ReceiveTypeEnum receiverType, String receiverId) {
        if (StringUtils.isBlank(receiverId)) {
            return "";
        }
        switch (receiverType) {
            case DEPT: {
                SysDept entityByDataId = sysDeptDao.getEntityByDataId(receiverId);
                if (entityByDataId == null) {
                    return "";
                }
                return StringUtils.isBlank(entityByDataId.deptShortName)
                        ? entityByDataId.deptName
                        : entityByDataId.deptShortName;
            }
            case ROLE: {
                SysRole entity = sysRoleDao.getEntityByDataId(receiverId);
                return entity == null
                        ? ""
                        : entity.roleName;
            }
            case USER: {
                return getUserName(receiverId);
            }
            case OTHER:
            default: {
                return "";
            }
        }
    }

    public String getUserName(String userId) {
        if (StringUtils.isBlank(userId)) {
            return "";
        }
        SysUser entity = sysUserDao.getEntityByDataId(userId);
        return entity == null
                ? ""
                : entity.userName;
    }
}
